home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / misc / elcheapofax.lha / apack.asm < prev    next >
Assembly Source File  |  1993-04-15  |  7KB  |  250 lines

  1.  
  2. ****************************************************************
  3. *
  4. *  Copyright 1988 by CREATIVE FOCUS.  This code is freely
  5. *  distributable as long as this notice is retained and no
  6. *  other conditions are imposed upon its redistribution.
  7. *
  8. *
  9. *  APACK.ASM --
  10. *
  11. *  A fully compatible replacement for Electronic Arts' PACKER.C
  12. *  routine.  Converts data according to the IFF ILBM cmpByteRun1
  13. *  compression protocol:
  14. *
  15. *     control bytes:
  16. *
  17. *     n =  0.. 127:     followed by n+1 bytes of data;
  18. *     n = -1..-127:     followed by byte to be repeated -n+1 times;
  19. *     n =     -128:     don't do no nada.
  20. *
  21. *     calling format:
  22. *
  23. *     long packrow(from, too, amt)
  24. *        char **from, /* pointer to source data pointer */
  25. *         **too;  /* pointer to destination data pointer */
  26. *        long amt;     /* number of bytes to compress */
  27. *
  28. *     return(number of bytes written to destination);
  29. *
  30. *     effects:
  31. *
  32. *      *from = *from + amt, and *too = *too + return;
  33. *      return is "smart," that is, not greater than
  34. *      MaxPackedSize = amt + ((amt+127) >> 7).
  35. *
  36. *     By commenting out CHECK (below) you disable checking for runs
  37. *     exceeding 128 bytes.  That CHECK is not needed if you are sure
  38. *     the amt to be compressed is always 128 or less.
  39. *
  40. *  !!! DISCLAIMER !!!  You use this code entirely at your own
  41. *  risk.  I don't warrantee its fitness for any purpose.  I
  42. *  can't even guarantee the accuracy of anything I've said
  43. *  about it, though I've tried my damndest to get it right.
  44. *  I may, in fact, be completely out of my tiny little mind :-).
  45. *
  46. *  That being said, I can be reached for questions, comments,
  47. *  or concerns at:
  48. *
  49. *     Dr. Gerald Hull
  50. *     CREATIVE FOCUS
  51. *     12 White Street
  52. *     Binghamton, N.Y.  13901
  53. *     (607) 648-4082
  54. *
  55. *     bix:     ghull
  56. *     PLink:  DRJERRY
  57. *
  58. ***************************************************************
  59.  
  60.       xdef  _PackRow
  61.  
  62. PT    equr  a0              -> beginning of replicate run (if any)
  63. IX    equr  a1              -> end+1 of input line
  64. IP    equr  a2              -> beginning of literal run (if any)
  65. IQ    equr  a3              -> end+1 of lit and/or rep run (if any)
  66. OP    equr  a4              -> end+1 of output line current pos
  67. FP    equr  a6              frame pointer
  68. SP    equr  a7              stack pointer
  69.  
  70. RT    equr  d0              return value
  71. MX    equr  d1              check for maximum run = MAX
  72. AM    equr  d2              amount
  73. CH    equr  d3              character
  74.  
  75. REGS  reg   AM/CH/IP/IQ/OP
  76.  
  77. FRM   equ   8              input line address
  78. TOO   equ   12              output line address
  79. AMT   equ   16              length of input line
  80.  
  81. MAX   equ   128           maximum encodable output run
  82. CHECK equ   1              turns on maximum row checking
  83.  
  84.  
  85. _PackRow
  86.  
  87.  
  88. ***************     CASE 0:   GRAB PARAMS & INITIALIZE
  89. CAS0
  90.       link     FP,#0
  91.       movem.l  REGS,-(SP)
  92.       movea.l  FRM(FP),IP
  93.       movea.l  (IP),IP        IP = *from
  94.       movea.l  IP,IQ          IQ = IP
  95.       movea.l  IQ,IX
  96.       adda.l   AMT(FP),IX     IX = IP + amt
  97.       movea.l  TOO(FP),OP
  98.       movea.l  (OP),OP        OP = *too
  99.  
  100.  
  101. ***************     CASE 1:   LITERAL RUN
  102. CAS1
  103.       movea.l  IQ,PT          adjust PT (no replicates yet!)
  104.       move.b   (IQ)+,CH       grab character
  105.       cmpa.l   IQ,IX          if input is finished
  106.       beq.s    CAS5         branch to case 5
  107.  
  108.       ifd      CHECK
  109.       move.l   IQ,MX
  110.       sub.l    IP,MX
  111.       cmpi     #MAX,MX          if run has reached MAX
  112.       beq.s    CAS6         branch to case 6
  113.       endc
  114.  
  115.       cmp.b    (IQ),CH        if next character != CH
  116.       bne.s    CAS1         stay in case 1
  117.  
  118. *                  else fall into case 2
  119.  
  120.  
  121. ***************     CASE 2:   AT LEAST 2 BYTE REPEAT
  122. CAS2
  123.       move.b   (IQ)+,CH       grab character
  124.       cmpa.l   IQ,IX          if input is finished
  125.       beq.s    CAS7         branch to case 7
  126.  
  127.       ifd      CHECK
  128.       move.l   IQ,MX
  129.       sub.l    IP,MX
  130.       cmpi     #MAX,MX          if run has reached MAX
  131.       beq.s    CAS6         branch to case 6
  132.       endc
  133.  
  134.       cmp.b    (IQ),CH        if next character != CH
  135.       bne.s    CAS1         branch to case 1
  136.  
  137. *                  else fall into case 3
  138.  
  139.  
  140. ***************     CASE 3:   REPLICATE RUN
  141. CAS3
  142.       move.b   (IQ)+,CH       grab character
  143.       cmpa.l   IQ,IX          if input is finished
  144.       beq.s    CAS7         branch to case 7
  145.  
  146.       ifd      CHECK
  147.       move.l   IQ,MX
  148.       sub.l    PT,MX
  149.       cmpi     #MAX,MX          if run has reached MAX
  150.       beq.s    CAS4         branch to case 4
  151.       endc
  152.  
  153.       cmp.b    (IQ),CH        if next character = CH
  154.       beq.s    CAS3         stay in case 3
  155.  
  156. *                  else fall into case 4
  157.  
  158.  
  159. ***************     CASE 4:   LIT AND/OR REP DUMP & CONTINUE
  160. CAS4
  161.       move.l   PT,AM
  162.       sub.l    IP,AM          AM = PT - IP
  163. *                  if no literal run
  164.       beq.s    C41         branch to replicate run
  165.  
  166.       subq     #1,AM          AM = AM - 1
  167.       move.b   AM,(OP)+       output literal control byte
  168.  
  169. C40   move.b   (IP)+,(OP)+    output literal run
  170.       dbra     AM,C40
  171.  
  172. C41   move.l   PT,AM
  173.       sub.l    IQ,AM          AM = PT - IQ (negative result!)
  174.       addq     #1,AM          AM = AM + 1
  175.       move.b   AM,(OP)+       output replicate control byte
  176.       move.b   CH,(OP)+       output repeated character
  177.       movea.l  IQ,IP          reset IP
  178.       bra.s    CAS1          branch to case 1 (not done)
  179.  
  180.  
  181. ***************     CASE 5:   LITERAL DUMP & QUIT
  182. CAS5
  183.       move.l   IQ,AM
  184.       sub.l    IP,AM          AM = IQ - IP (positive result > 0)
  185.       subq     #1,AM          AM = AM - 1
  186.       move.b   AM,(OP)+       output literal control byte
  187.  
  188. C50   move.b   (IP)+,(OP)+    output literal run
  189.       dbra     AM,C50
  190.  
  191.       bra.s    CAS8          branch to case 8 (done)
  192.  
  193.  
  194.       ifd      CHECK
  195.  
  196. ***************     CASE 6:   LITERAL DUMP & CONTINUE
  197. CAS6
  198.       move.l   IQ,AM
  199.       sub.l    IP,AM          AM = IQ - IP (positive result > 0)
  200.       subq     #1,AM          AM = AM - 1
  201.       move.b   AM,(OP)+       output literal control byte
  202.  
  203. C60   move.b   (IP)+,(OP)+    output literal run
  204.       dbra     AM,C60
  205.  
  206.       bra      CAS1          branch to case 1 (not done)
  207.  
  208.       endc
  209.  
  210.  
  211. ***************     CASE 7:   LIT AND/OR REP DUMP & FINISH
  212. CAS7
  213.       move.l   PT,AM
  214.       sub.l    IP,AM          AM = PT - IP (positive result > 0)
  215. *                  if no literal run
  216.       beq.s    C71         branch to replicate run
  217.  
  218.       subq     #1,AM          AM = AM - 1
  219.       move.b   AM,(OP)+       output literal control byte
  220.  
  221. C70   move.b   (IP)+,(OP)+    output literal run
  222.       dbra     AM,C70
  223.  
  224. C71   move.l   PT,AM
  225.       sub.l    IQ,AM          AM = PT - IQ (negative result)
  226.       addq     #1,AM          AM = AM + 1
  227.       move.b   AM,(OP)+       output replicate control byte
  228.       move.b   CH,(OP)+       output repeated character
  229.  
  230. *                  fall into case 8
  231.  
  232.  
  233. ***************     CASE 8:   ADJUST PARAMS & RETURN VALUE
  234. CAS8
  235.       movea.l  FRM(FP),PT     PT = **from
  236.       move.l   IQ,(PT)        *from = *from + amt
  237.       movea.l  TOO(FP),PT     PT = **too
  238.  
  239.       move.l   OP,RT
  240.       sub.l    (PT),RT       return = OP - *too
  241.  
  242.       move.l   OP,(PT)       *too = *too + return
  243.       movem.l  (SP)+,REGS
  244.       UNLK     FP
  245.       rts
  246.  
  247.       end
  248.  
  249.  
  250.